package com.cas.jms.parser;

import com.cas.annotation.Mq;
import org.bson.BasicBSONObject;
import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
@Mq(name = "HJ212")
public class HJ212Parser implements Parser {

    @Resource
    private MongoTemplate mongoTemplate;

    private final Pattern ST = Pattern.compile("ST=(?<ST>\\w{2});");
    private final Pattern CN = Pattern.compile("CN=(?<CN>\\w{4});");

    private final Pattern PW = Pattern.compile("PW=(?<PW>\\w{6});");

    private final Pattern MN = Pattern.compile("MN=(?<MN>(\\w|-|[\u4e00-\u9fa5])+);");

    private final Pattern CP = Pattern.compile("CP=&&(?<CP>(\\w|\\W)+)&&");

    String collectionNameFormat = "ST%s_CN%s";


    private String getMatchValue(Pattern pattern, String text) {
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }

    @Override
    public void process(String text) {
        Document document = new Document();

        String st = getMatchValue(ST, text);
        String cn = getMatchValue(CN, text);
        if (st == null || cn == null) {
            return;
        }

        String collectionName = String.format(collectionNameFormat, st, cn);


        Criteria criteria = new Criteria();
        String mn = getMatchValue(MN, text);
        if (mn != null) {
            document.put("mn", mn);
            criteria.and("mn").is(mn);
        }

        String cp = getMatchValue(CP, text);
        if (cp != null) {
            String[] dataArray = cp.split(";");
            for (String data : dataArray) {
                String[] itemArray = data.split(",");
                for (String item : itemArray) {
                    String[] kv = item.split("=");
                    if (kv.length == 2) {
                        String key = kv[0];
                        String value = kv[1];
                        if (key.equals("DataTime")) {
                            LocalDateTime dataTime = LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
                            document.put("dataTime", dataTime);
                            criteria.and("dataTime").is(dataTime);
                        } else {
                            String[] factorKey = key.split("-");
                            if (factorKey.length == 2) {
                                String factor = factorKey[0];
                                String field = factorKey[1];
                                if (!document.containsKey(factor)) {
                                    BasicBSONObject bsonObject = new BasicBSONObject();

                                    bsonObject.put(field, value);
                                    document.put(factor, bsonObject);
                                } else {
                                    document.get(factor, BasicBSONObject.class).put(field, value);
                                }
                            } else if (factorKey.length == 1) {
                                String factor = factorKey[0];
                                document.put(factor, value);
                            }
                        }
                    }
                }
            }
        }

        Query query = new Query();
        query.addCriteria(criteria);
        Update update = Update.fromDocument(document);
        mongoTemplate.upsert(query, update, collectionName);
    }
}
